using CodePen.Server.Language;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using System.Data;

namespace CodePen.Server.Service;

/// <summary>
/// 
/// </summary>
[ApiExplorerSettings(GroupName = "CodePen")]
public partial class ContentService : IApplicationService
{
    /// <summary>
    /// 
    /// </summary>
    private readonly SugarRepository<PickContent> _thisRepository;
    private readonly SugarRepository<PickCategory> _categoryRepository;
    private readonly ICurrentUser _currentUser;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="thisRepository"></param>
    /// <param name="categoryRepository"></param>
    /// <param name="currentUser"></param>
    public ContentService(SugarRepository<PickContent> thisRepository,
        SugarRepository<PickCategory> categoryRepository,
        ICurrentUser currentUser)
    {
        _thisRepository = thisRepository;
        _categoryRepository = categoryRepository;
        _currentUser = currentUser;
    }

    /// <summary>
    /// 获取Dashboard统计数据
    /// </summary>
    /// <returns>返回内容统计数据</returns>
    public async Task<RestfulResult<object>> GetDashboardStatsAsync()
    {
        var restful = new RestfulResult<object>() { Code = CodeStatus.OK };

        // 根据用户权限过滤数据
        var query = _thisRepository.AsQueryable()
            .WhereIF(!_currentUser.IsTenantAdmin && !_currentUser.IsSuperAdmin,
                     u => u.Creator == _currentUser.UserId)
            .Includes(p => p.Category); // 加载分类关联数据

        // 获取所有内容数据
        var allContents = await query.ToListAsync();

        // 计算统计数据
        var totalContents = allContents.Count;
        var activeContents = allContents.Count(c => c.IsDisable == YesOrNot.N);
        var disabledContents = totalContents - activeContents;

        // 获取最近添加的内容（限制前10条）
        var recentContents = allContents
            .Where(c => c.IsDisable == YesOrNot.N)
            .OrderByDescending(c => c.CreateTime)
            .Take(10)
            .Select(c => new
            {
                id = c.Id,
                content = c.Content,
                category = c.Category?.Name ?? "未分类",
                createTime = c.CreateTime
            }).ToList();

        // 获取分类内容分布
        var categoryDistribution = allContents
            .Where(c => c.IsDisable == YesOrNot.N && c.Category != null)
            .GroupBy(c => c.Category.Name)
            .Select(g => new { name = g.Key, value = g.Count() })
            .ToList();

        // 构建返回数据
        restful.Data = new
        {
            totalContents,
            activeContents,
            disabledContents,
            recentContents,
            categoryDistribution
        };

        return restful;
    }

    /// <summary>
    /// 查询所有/分页
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns> 
    public async Task<RestfulResult<PageResult<PickContent>>> GetPagesAsync(ContentPageParam? data)
    {
        var restful = new RestfulResult<PageResult<PickContent>>() { Code = CodeStatus.OK };
        data ??= new ContentPageParam { PageNo = 1, PageSize = 10 };
        var query = await _thisRepository.AsQueryable()
           .WhereIF(!_currentUser.IsTenantAdmin && !_currentUser.IsSuperAdmin, u => u.Creator == _currentUser.UserId)
            .WhereIF(data.Content.NotNullOrWhiteSpace(), u => u.Content.Contains(data.Content))
            .WhereIF(data.CategoryId.HasValue, u => u.CategoryId == data.CategoryId)
            .WhereIF(data.IsDisable.HasValue, u => u.IsDisable == data.IsDisable)
            .OrderByDescending(c => c.CreateTime)
            .ToPageAsync(data.PageNo, data.PageSize);

        restful.Data = query;
        return restful;
    }

    /// <summary>
    /// 查询所有/分页
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns> 
    public async Task<RestfulResult<PageResult<PickContent>>> GetAllPagesAsync(ContentPageParam? data)
    {
        var restful = new RestfulResult<PageResult<PickContent>>() { Code = CodeStatus.OK };
        data ??= new ContentPageParam { PageNo = 1, PageSize = 10 };
        var query = await _thisRepository.AsQueryable()
            .WhereIF(data.Content.NotNullOrWhiteSpace(), u => u.Content.Contains(data.Content))
            .WhereIF(data.CategoryId.HasValue, u => u.CategoryId == data.CategoryId)
            .WhereIF(data.IsDisable.HasValue, u => u.IsDisable == data.IsDisable)
            .Includes(p => p.Category)
            .OrderByDescending(c => c.CreateTime)
            .ToPageAsync(data.PageNo, data.PageSize);

        restful.Data = query;
        return restful;
    }
    /// <summary>
    /// 所有
    /// </summary>
    /// <returns></returns>
    public async Task<RestfulResult<PageResult<PickContent>>> GetlistAsync()
    {
        var restful = new RestfulResult<PageResult<PickContent>>() { Code = CodeStatus.OK };
        PageParam data = new PageParam { PageNo = 1, PageSize = 100 };
        var query = await _thisRepository.AsQueryable()
             .Where(u => u.IsDisable == YesOrNot.N)
             .Where(u => u.Creator == _currentUser.UserId)
             .OrderByDescending(u => u.CreateTime)
             .ToPageAsync(data.PageNo, data.PageSize);
        restful.Data = query;
        return restful;
    }

    /// <summary>
    /// 增加
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    [UnitOfWork]
    public async Task<RestfulResult> AddAsync(PickContent data)
    {
        RestfulResult restful = new() { Code = CodeStatus.BadRequest };

        // 检查内容是否已存在
        var isExist = await _thisRepository.IsAnyAsync(u => u.Content == data.Content);
        if (isExist)
        {
            restful.Message = i18n.data_duplicate;
            return restful;
        }

        data.Creator = _currentUser.UserId;
        bool result = await _thisRepository.InsertAsync(data);
        if (result)
        {
            restful.Data = result;
            restful.Code = CodeStatus.OK;
            return restful;
        }
        else
        {
            restful.Message = $"{i18n.add}{i18n.fail}";
            return restful;
        }
    }

    /// <summary>
    /// 更新
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public async Task<RestfulResult> UpdateAsync(PickContent data)
    {
        RestfulResult restful = new() { Code = CodeStatus.BadRequest };
        var isExist = await _thisRepository.IsAnyAsync(u => u.Id == data.Id);
        if (!isExist)
        {
            restful.Message = $"{i18n.not_exist}";
            return restful;
        }

        // 检查是否有其他记录已存在相同内容
        var isContentDuplicate = await _thisRepository.IsAnyAsync(u =>
            u.Content == data.Content &&
            u.Id != data.Id);

        if (isContentDuplicate)
        {
            restful.Message = i18n.data_duplicate;
            return restful;
        }

        bool result = await _thisRepository.UpdateAsync(data, true, true, $"{i18n.modify}");
        if (result)
        {
            restful.Data = result;
            restful.Code = CodeStatus.OK;
            return restful;
        }
        else
        {
            restful.Message = $"{i18n.modify}{i18n.fail}";
            return restful;
        }
    }

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns> 
    public async Task<RestfulResult> DeleteAsync([FromBody] EntityBaseId data)
    {
        RestfulResult restful = new() { Code = CodeStatus.BadRequest };

        if (data.Id == 0)
        {
            restful.Message = $"{i18n.delete}{i18n.fail}";
            return restful;
        }
        bool isDelete = await _thisRepository.DeleteByIdAsync(data.Id);
        if (isDelete)
        {
            restful.Data = isDelete;
            restful.Message = $"{i18n.delete}{i18n.success}";
            restful.Code = CodeStatus.OK;
            return restful;
        }
        else
        {
            restful.Data = isDelete;
            restful.Message = $"{i18n.delete}{i18n.fail}";
            return restful;
        }
    }

    // 导出模板功能已迁移到前端处理


    /// <summary>
    /// 导入数据
    /// </summary>
    /// <param name="fileContent">文件内容</param>
    /// <returns></returns>
    public async Task<RestfulResult<object>> ImportAsync(byte[] fileContent)
    {
        var restful = new RestfulResult<object> { Code = CodeStatus.BadRequest };
        var contents = new List<PickContent>();
        int successCount = 0;
        int failCount = 0;
        int duplicateCount = 0;

        try
        {
            // 获取所有可用分类（用于名称到ID的转换）
            var categories = await _categoryRepository.AsQueryable()
                .Where(c => c.IsDisable == YesOrNot.N)
                .ToListAsync();

            // 创建分类名称到ID的映射字典
            var categoryMap = categories.ToDictionary(c => c.Name.Trim(), c => c.Id, StringComparer.OrdinalIgnoreCase);

            // 获取当前用户已有的所有内容（用于检查重复）
            var existingContents = await _thisRepository.AsQueryable()
                .Select(c => c.Content)
                .ToListAsync();

            // 创建现有内容的HashSet，用于快速查找
            var existingContentSet = new HashSet<string>(existingContents, StringComparer.OrdinalIgnoreCase);

            // 使用MiniExcel处理Excel文件
            using (var stream = new MemoryStream(fileContent))
            {
                // 使用MiniExcel读取Excel数据，使用DataTable来处理
                var dataTable = await MiniExcel.QueryAsDataTableAsync(stream);

                // 检查是否有数据
                if (dataTable == null || dataTable.Rows.Count <= 1) // <=1 因为第一行是表头
                {
                    restful.Message = "Excel文件中未找到有效数据";
                    return restful;
                }

                // 遍历所有数据行（从第二行开始，跳过表头）
                for (int i = 1; i < dataTable.Rows.Count; i++)
                {
                    try
                    {
                        DataRow row = dataTable.Rows[i];

                        // 获取单元格值（假设第一列为分类，第二列为内容）
                        string categoryName = string.Empty;
                        string content = string.Empty;

                        // 获取第一列的值
                        if (dataTable.Columns.Count > 0 && row[0] != DBNull.Value)
                        {
                            categoryName = row[0].ToString()?.Trim() ?? string.Empty;
                        }

                        // 获取第二列的值
                        if (dataTable.Columns.Count > 1 && row[1] != DBNull.Value)
                        {
                            content = row[1].ToString()?.Trim() ?? string.Empty;
                        }

                        // 验证必填字段
                        if (string.IsNullOrEmpty(categoryName) || string.IsNullOrEmpty(content))
                        {
                            failCount++;
                            continue;
                        }

                        // 查找分类ID
                        if (!categoryMap.TryGetValue(categoryName, out long categoryId))
                        {
                            failCount++;
                            continue;
                        }

                        // 检查内容是否已存在
                        if (existingContentSet.Contains(content))
                        {
                            duplicateCount++;
                            continue; // 跳过已存在的内容
                        }

                        // 创建内容对象（默认启用状态）
                        PickContent pickContent = new PickContent
                        {
                            CategoryId = categoryId,
                            Content = content,
                            IsDisable = YesOrNot.N, // 默认启用
                            Creator = _currentUser.UserId,
                            CreateTime = DateTime.Now
                        };

                        contents.Add(pickContent);
                        // 将新内容添加到现有集合中，避免后续重复检查
                        existingContentSet.Add(content);
                        successCount++;
                    }
                    catch (Exception)
                    {
                        failCount++;
                    }
                }
            }

            // 批量插入数据
            if (contents.Any())
            {
                await _thisRepository.InsertRangeAsync(contents);
            }

            // 设置返回结果
            restful.Code = CodeStatus.OK;
            restful.Message = $"导入成功{successCount}条，失败{failCount}条，重复数据{duplicateCount}条（已跳过）";
            restful.Data = new { successCount, failCount, duplicateCount };

            return restful;
        }
        catch (Exception ex)
        {
            restful.Message = $"导入失败：{ex.Message}";
            return restful;
        }
    }
}

